/*
 * To change this template, choose Tools | Templates and open the template in
 * the editor.
 */
package br.jm.mala.util;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import net.sf.trugger.element.Element;
import net.sf.trugger.element.Elements;
import static net.sf.trugger.scan.ClassScan.findClasses;

/**
 *
 * @author joao
 */
public class Configuracao implements Serializable {

    private static final long serialVersionUID = -4809426264693119046L;

    private Map<String, String> camposMap;
    private Map<String, String> camposMapType;
    public static HashMap<String, Map> tabelasMap;
    private Column annotation;
    private ConfiguraCampoAnnotation configuraCampo;
    private String nomeColuna;
    private String nomeEntidade;
    private String type;
    private String cNomMap;
    private String cNomMapType;
    private String cNomeTabela;
    private String nomeTabelaJoin;

    public Configuracao() {
    }

    public void gravaObjeto() throws Exception {
        try {
            //ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("configuration.bin"));
            Set<Class> classes = findClasses().recursively().annotatedWith(Entity.class).in("br.jm.mala.entity");
            Object[] nomeEntidades = classes.toArray();
            tabelasMap = new HashMap<>();

            for (Object nomeEntidade1 : nomeEntidades) {
                Set<Element> columns = Elements.elements().annotatedWith(Column.class).in(nomeEntidade1);
                Set<Element> columnsConfigura = Elements.elements().annotatedWith(ConfiguraCampoAnnotation.class).in(nomeEntidade1);
                cNomMap = nomeEntidade1.toString().replace("class br.jm.mala.entity.", "");
                cNomMapType = cNomMap.concat("Type");
                camposMap = new HashMap<>();
                camposMapType = new HashMap<>();
                if (columnsConfigura.size() > 0) {
                    columnsConfigura.stream().map((element) -> {
                        configuraCampo = element.getAnnotation(ConfiguraCampoAnnotation.class);
                        return element;
                    }).map((_item) -> {
                        nomeTabelaJoin = configuraCampo.nomeTabelJoin();
                        return _item;
                    }).map((_item) -> {
                        nomeColuna = nomeTabelaJoin.concat(".").concat(configuraCampo.campo());
                        return _item;
                    }).map((_item) -> {
                        nomeEntidade = configuraCampo.pesquisa();
                        return _item;
                    }).map((_item) -> {
                        type = configuraCampo.tipo();
                        return _item;
                    }).map((_item) -> {
                        camposMap.put(nomeEntidade, nomeColuna);
                        return _item;
                    }).forEach((_item) -> {
                        camposMapType.put(nomeEntidade, type);
                    });
                }
                columns.stream().map((element) -> {
                    annotation = element.getAnnotation(Column.class);
                    return element;
                }).map((element) -> {
                    nomeColuna = annotation.name();
                    return element;
                }).map((element) -> {
                    nomeEntidade = element.name();
                    return element;
                }).map((element) -> {
                    type = element.type().toString();
                    return element;
                }).filter((_item) -> (!camposMap.containsKey(nomeEntidade))).map((_item) -> {
                    camposMap.put(nomeEntidade, nomeColuna);
                    return _item;
                }).forEach((_item) -> {
                    camposMapType.put(nomeEntidade, type);
                });
                camposMap.put(cNomMap, retornaSql(cNomMap));
                camposMap.put("Order", retornaOrder(cNomMap));
                tabelasMap.put(cNomMap, camposMap);
                tabelasMap.put(cNomMapType, camposMapType);
            }
        } catch (Exception e) {
            throw e;
        }

    }
    /*
     * public Map leObjeto(String cCampo) throws FileNotFoundException,
     * IOException { HashMap<String, Map> obj = null; try { ObjectInputStream in
     * = new ObjectInputStream(new FileInputStream("configuration.bin")); obj =
     * (HashMap<String, Map>) in.readObject(); camposMap = obj.get(cCampo);
     * in.close(); } catch (Exception e) { e.printStackTrace(); }
     *
     * return camposMap; }
     *
     * public Map leObjetoType(String cCampo) throws FileNotFoundException,
     * IOException { HashMap<String, Map> obj = null; try { ObjectInputStream in
     * = new ObjectInputStream(new FileInputStream("configuration.bin")); obj =
     * (HashMap<String, Map>) in.readObject(); camposMapType = obj.get(cCampo);
     * in.close(); } catch (Exception e) { e.printStackTrace(); }
     *
     * return camposMapType; }
     *
     *
     */

    private String retornaSql(String cTabela) {
        String cSql = null;

        switch (cTabela) {
            case "Atividade":
                cSql = "with paginacao as ( "
                        + "SELECT row_number() over (order by par1 par2 ) as 'rownumber', "
                        + "id_atividade,CodMix,DescMix "
                        + "FROM atividade ";
                break;
            case "CategoriaGrupo":
                cSql = "with paginacao as ( "
                        + "SELECT row_number() over (order by par1 par2 ) as 'rownumber', "
                        + "id_grupo, dsc_grupo "
                        + "FROM categoria_grupo ";
                break;
            case "Categoria":
                cSql = "with paginacao as ( "
                        + "SELECT row_number() over (order by par1 par2 ) as 'rownumber', "
                        + "id_categoria, dsc_categoria "
                        + "FROM categoria ";
                break;
            case "User":
                cSql = "with paginacao as ( "
                        + "SELECT row_number() over (order by par1 par2 ) as 'rownumber', "
                        + "user_id,user_password,user_username,theme,nom_user,e_mail "
                        + "FROM users ";
                break;
            case "Roles":
                cSql = "with paginacao as ( "
                        + "SELECT row_number() over (order by par1 par2 ) as 'rownumber', "
                        + "role_id,description,nom_fantasia "
                        + "FROM roles ";
                break;
            case "CepEndereco":
                cSql = "with paginacao as ( "
                        + "SELECT row_number() over (order by par1 par2 ) as 'rownumber', "
                        + "cep_endereco.cod_logradouro,cep_endereco.dsc_logradouro,cep_endereco.num_cep,"
                        + "cep_bairro.cod_bairro,cep_bairro.dsc_bairro,cep_cidade.cod_cidade, "
                        + "cep_cidade.dsc_cidade,cep_uf.cod_uf, "
                        + "cep_uf.dsc_estado "
                        + "FROM cep_endereco INNER JOIN cep_bairro ON cep_endereco.cod_bairro = cep_bairro.cod_bairro "
                        + "INNER JOIN cep_cidade ON cep_bairro.cod_cidade = cep_cidade.cod_cidade "
                        + "INNER JOIN cep_uf ON cep_cidade.cod_uf = cep_uf.cod_uf ";
                break;
            case "CepBairro":
                cSql = "with paginacao as ( "
                        + "SELECT row_number() over (order by par1 par2 ) as 'rownumber', "
                        + "cep_bairro.cod_bairro,cep_bairro.dsc_bairro,cep_cidade.cod_cidade, "
                        + "cep_cidade.dsc_cidade,cep_uf.cod_uf, "
                        + "cep_uf.dsc_estado "
                        + "FROM cep_bairro INNER JOIN cep_cidade ON cep_bairro.cod_cidade = cep_cidade.cod_cidade "
                        + "INNER JOIN cep_uf ON cep_cidade.cod_uf = cep_uf.cod_uf";
                break;
            case "Modulos":
                cSql = "with paginacao as ( "
                        + "SELECT row_number() over (order by par1 par2 ) as 'rownumber', "
                        + "modulo_id,description,dsc_modulo,num_nivel,ordem,menu "
                        + "FROM modulos ";
                break;
            case "Sucmala":
                cSql = "with paginacao as ( "
                        + "SELECT row_number() over (order by par1 par2 ) as 'rownumber', "
                        + "id_suc,Suc,Fantasia,suc_mala.cod_logradouro,numero,complemento,Contato,Telefone,Ramal,RazSoc,TeleLoja,Item,Entrega,suc_mala.id_categoria, "
                        + "suc_mala.id_grupo,CGC,IE,Fax,Area,Obs,suc_mala.id_atividade,Email,Email2, "
                        + "cep_endereco.dsc_logradouro,cep_endereco.num_cep, "
                        + "cep_bairro.cod_bairro,cep_bairro.dsc_bairro,cep_cidade.cod_cidade, "
                        + "cep_cidade.dsc_cidade,cep_uf.cod_uf,cep_uf.dsc_estado "
                        + "FROM suc_mala INNER JOIN atividade ON suc_mala.id_atividade = atividade.id_atividade "
                        + "INNER JOIN categoria ON suc_mala.id_categoria = categoria.id_categoria "
                        + "INNER JOIN categoria_grupo ON suc_mala.id_grupo = categoria_grupo.id_grupo "
                        + "INNER JOIN cep_endereco ON suc_mala.cod_logradouro = cep_endereco.cod_logradouro "
                        + "INNER JOIN cep_bairro ON cep_endereco.cod_bairro = cep_bairro.cod_bairro "
                        + "INNER JOIN cep_cidade ON cep_bairro.cod_cidade = cep_cidade.cod_cidade "
                        + "INNER JOIN cep_uf ON cep_cidade.cod_uf = cep_uf.cod_uf ";
                break;
        }

        return cSql;
    }

    private String retornaOrder(String cTabela) {
        String cOrder = null;

        switch (cTabela) {
            case "Atividade":
                cOrder = " DescMix ";
                break;
            case "CategoriaGrupo":
                cOrder = " dsc_grupo ";
                break;
            case "Categoria":
                cOrder = " dsc_categoria ";
                break;
            case "User":
                cOrder = " nom_user ";
                break;
            case "Roles":
                cOrder = " nom_fantasia ";
                break;
            case "CepEndereco":
                cOrder = " dsc_logradouro ";
                break;
            case "CepBairro":
                cOrder = " dsc_bairro ";
                break;
            case "Modulos":
                cOrder = " num_nivel, ordem ";
                break;
            case "Sucmala":
                cOrder = " fantasia ";
                break;
        }

        return cOrder;
    }
}
